asynx.impl.util = {
	
	curry: function(fn, scope) {
	    var scope = scope || window;
	    var args = [];

	    for (var i=2, len = arguments.length; i < len; ++i) {
	        args.push(arguments[i]);
	    };
	    return function() {
		    fn.apply(scope, args);
	    };
	},
	
	executeOn: function(rFunc, delay) {
		var scope = arguments[3];
		var cyclic = arguments[2];
		var timeOut = setInterval(
		function() {
			rFunc.apply(scope);
			if (!cyclic) clearInterval(timeOut);
		}
		, delay ? delay : 0);
		
		return timeOut;
	},
	
	delay: function(rFunc, delay) {
		return asynx.executeOn(rFunc, delay, arguments[2], arguments[3]);
	},
		
	evalJSON: function(json) {
		return json?eval("(" + json + ")"):false;
	},
	
	createIframe : function(frameId){
		var body = asynx$("/body");
		var iframe = null;
		var append = arguments[1]==false?false:true;
		
		if (asynx.isIE) {
			iframe = document.createElement('<iframe onload="" id="' + frameId + '" name="' + frameId + '" />');
		}else{
			iframe = document.createElement('iframe');
			iframe.name = frameId;
			iframe.id = frameId;
		}
		asynx.fling(iframe);
		
		if (append)
			body.appendChild(iframe);
			
		return iframe;
	},
	
	//throws out screen
	fling: function(rNode) {
		var element = asynx$(rNode);
		element.style.position = 'absolute';
		element.style.top = '-1000px';
		element.style.left = '-1000px';
	},
	
	// fix zindex IE problem
	fixzIndex: function(el) {
		var uid = 'asynx_fixzIndex_'+asynx.uid();
		var iframe = asynx(asynx.createIframe(uid, false));
		el = asynx(el);
		el.zIndexFixer = uid;
		
		asynx.dom.before(el, iframe);
		
		iframe.css({
			zIndex: 0,
			top: el.css('top'),
			left: el.css('left'),
			width: el.css('width'),
			height: el.css('height'),
			border: '0px none',
			filter: 'mask()',
			position: 'absolute'
		});
		
		return iframe;
	},
	
	iframeDoc: function(iframe) {
		var iDoc;
		
		// for NS6
		if (iframe.contentDocument)
			iDoc = iframe.contentDocument;
		// for ie5.5 and ie6
		else if (iframe.contentWindow)
			iDoc = iframe.contentWindow.document;
		// for ie5
		else if (iframe.document)
			iDoc = iframe.document;
			
		return iDoc;
	},
	
	
	importScript: function(src){
		var scriptElem = document.createElement('script');
		var ms = new Date().getTime().toString(), seed = "?" + ms;
		var cache = arguments[1], container = asynx.isOpera ? asynx('/body') : asynx('/head');
		scriptElem.setAttribute('src', src + (cache?seed:""));
		scriptElem.setAttribute('type','text/javascript');
		container.appendChild(scriptElem);
	},

	createScript: function(rScript) {
		var body = asynx$('/body');
		var script = document.createElement('script');
		 
		script.type = 'text/javascript';
		
		if (rScript.src)
			script.src = rScript.src;
		else
			script.text = rScript.text;
			
		body.appendChild(script);
	},
	
	reviveScriptTags: function(rObj) {
		var scriptTags = rObj.getElementsByTagName('script');
		for (var x = 0; x < scriptTags.length; x++) {
			var script = scriptTags[x];
			asynx.createScript(script);
		}
	},
	
	evalScriptTags: function(html) {
		var body = asynx$("/body");
		var jsdiv = document.createElement("div");
		
		// prevent IE bug
		var hidden = "<span style='position:absolute;left:-1000px;top:-1000px;'>&nbsp;</span>";
		
		body.appendChild(jsdiv);
		asynx.fling(jsdiv);
		jsdiv.innerHTML = hidden+html;
		asynx.reviveScriptTags(jsdiv);
		body.removeChild(jsdiv);
	},
	
	
	serializeForm: function(form) {
		
		form = asynx(form);
		var reArray = /.*\[\]/, sb = new asynx.StringBuffer(), fileds = arguments[1];
		
		if (fileds) fields = asynx.arrayTrim(fileds.split(","));
		
		for (var x = 0; x < form.elements.length; x++) {
			
			var element = form.elements[x],	concat = !!(x+1 < form.elements.length),
					type = element.type.toLowerCase(), name = element.name,
						elementName = reArray.test(name)?name:name+'[]';
			
			if (fileds && !asynx.isInArray(type, fields)) continue;
				
			if (!element.disabled) {
				var isInBlockedList = { "radio": true, "checkbox": true, "select-multiple": true }; 
				var canAddThisObject = !isInBlockedList[element.type];
				
				 // adding simple objects
				if (canAddThisObject || element.checked) {
					sb.append(element.name + "=");
					sb.append(encodeURIComponent(element.value));
					if (concat)	sb.append("&");
				}
					
				 // adding values for multiples selects
				if (element.type == 'select-multiple') {
					for (var i = 0; i < element.options.length; i++) {
						if (element.options[i].selected == true) {
							sb.append(elementName + "=" + encodeURIComponent(element.options[i].value));
							if (concat)	sb.append("&");
						}
					}
				}
			}
		}
		
		return sb.toString();
	},
	
	uid: function() {
		return [Math.random()].
			join("").match(/^\d\.(\d+)/)[1];
	},
	
	css: function(el, s) {

		var nodes = asynx(el);
		
		var shortCuts = {
			'c':'color',
			'bg':'backgroundColor',
			'bgColor':'backgroundColor',
			'bgAttach':'backgroundAttachment',
			'bgImage':'backgroundImage',
			'bgPosition':'backgroundPosition',
			'bgRepeat':'backgroundRepeat',
			'radius':'MozBorderRadius',
			'opacity':'opacity',
			'alpha':'opacity',
			'pad':'padding',
			'w':'width',
			'h':'height'
		};
		
		if (asynx.isArray(nodes) && !nodes.length) return false;
		
		var alphaIE = /alpha\(opacity=(\d+)\)/;
		
		if (asynx.isString(s)) {
			
			nodes = asynx.isArray(nodes)?nodes[0]:nodes;
			
			var isAlpha = /opacity|alpha/.test(s);
			
			style = isAlpha ? (asynx.isIE ? "filter" : "opacity") : s;
			
			var css = asynx.curCss(nodes, style);
			
			if (asynx.isIE && isAlpha && style == "filter") {
				var m = css.match(alphaIE);
				return m ? m[1] : css;
			}
			
			return css;
		}
		
		nodes.each(function(node, x) {
			asynx.forEach(s, function(k, v) {
				
				var link = shortCuts[k] || k;
				
				if (/opacity/.test(link)) {
					
					if (asynx.isIE) {
						link = "filter";
						v = alphaIE.test(v) ? v : "alpha(opacity="+asynx.stripUnit(v)+");";
					}
					else {
						v = asynx.stripUnit(v)/100;
					}
					
				}
				
				if (asynx.isIE && !node.currentStyle.hasLayout) {
					node.style.zoom = 1;
				}
				
				node.style[link] = v;
				
			});
		});
	},
	
	curCss: function(el, s) {
		var element = asynx(el), v = "";
		
		if (asynx.isArray(element) && !element.length) return false;

		if (element.currentStyle)
			v = element.currentStyle[s];
			
		else if (window.getComputedStyle)
			v = document.defaultView.getComputedStyle(element,null).getPropertyValue(s);
		
		if (/top|left/i.test(s))
			return asynx.getXY(element)[ s == "left" ? 0 : 1 ];	
		
		if (/width/i.test(s))
			return el.offsetWidth;
		
		if (s.match("height"))
			return el.offsetHeight;
		
		return v;
	},
	
	getXY: function(element) {
		var obj = element;
	    var x = 0;
	    var y = 0;
	   
	    if (obj.offsetParent) {
	        while (obj.offsetParent) {
	            x += obj.offsetLeft;
	            obj = obj.offsetParent;
	        }
	    }
	    else if (obj.x)
	        x += obj.x;
	       
	    obj = element;
	    if (obj.offsetParent) {
	        while (obj.offsetParent ) {
	            y += obj.offsetTop;
	            obj = obj.offsetParent;
	        }
	    }
	    else if (obj.y)
	        y += obj.y;

	    return [x,y];  
	},
	
	selectTextRange: function (inputText, iStart, iLength) {
	    if (inputText.createTextRange) {
	        var oRange = inputText.createTextRange();
	        oRange.moveStart("character", iStart);
	        oRange.moveEnd("character", iLength - inputText.value.length);
	        oRange.select();
	    } else if (inputText.setSelectionRange) {
	        inputText.setSelectionRange(iStart, iLength);
	    }
	    inputText.focus();
	},
	
	html: function(element, html) {
		var args = asynx.A(arguments);
		var evals = args[2];
		asynx(element).each(function(node){
			node.innerHTML = html;
			if (evals || evals == undefined)
				asynx.evalScriptTags(html);	
		}, this);
		
		return element;
	},
	
	setXY: function(el,x,y) {
		el.css({ top: y, left: x });
	},
	
	stripUnit: function(s) {
		return [s].join("").replace(/in|cm|mm|pt|pc|px|em|ex|%/, "");
	},
	
	StringBuffer: function() {
		this.buffer = [];
		
		this.append = function(b) {
			this.buffer[this.buffer.length] = b;
		};
	
		this.toString = function() {
			return this.buffer.join("");
		};
	},
	
	getPageScroll: function(){
		var x,y;
		if (self.pageYOffset) {
			x = self.pageXOffset;
			y = self.pageYOffset;
		}
		else if (document.documentElement && document.documentElement.scrollTop) {
			x = document.documentElement.scrollLeft;
			y = document.documentElement.scrollTop;
		}
		else if (document.body) {
			x = document.body.scrollLeft;
			y = document.body.scrollTop;
		}
		return [x,y];
	},
	
	getPageSize: function(){
		var x,y;
		var sHeight = document.body.scrollHeight;
		var oHeight = document.body.offsetHeight
		if (sHeight > oHeight) {
			x = document.body.scrollWidth;
			y = document.body.scrollHeight;
		}
		else {
			// explorer mac and also: explorer 6, mozilla and safari
			x = document.body.offsetWidth;
			y = document.body.offsetHeight;
		}
		
		return [x,y];
	},
	
	disableSelection: function(element) {
	    element.onselectstart = function() {
	        return false;
	    };
	    element.unselectable = "on";
	    element.style.MozUserSelect = "none";
	},
	
	enableSelection: function(element) {
	    element.onselectstart = function() {
	        return true;
	    };
	    element.unselectable = "off";
	    element.style.MozUserSelect = "";
	}

};


asynx.extend(asynx, asynx.impl.util);
delete asynx.impl.util;